react + typescript + materialUI(Mui)系统基础搭建

您所在的位置:网站首页 react typescript模板 react + typescript + materialUI(Mui)系统基础搭建

react + typescript + materialUI(Mui)系统基础搭建

2024-06-10 16:25| 来源: 网络整理| 查看: 265

react + typescript + materialUI(Mui)系统基础搭建

首先根据 React with TypeScript and Less 这篇教程的介绍搭建基于TypeScript+Less的React项目

然后安装react需要用到的库react-router-dom和react-redux

yarn add react-router-dom yarn add react-redux 技术选型 框架: React + reatc-router + react-redux编程语言:TypeScript + lessUI: Material UI (Mui) Day 01 项目搭建

​ 基于React with TypeScript and Less 这篇教程搭建项目

安装Mui组件库 // 使用 yarn 安装 yarn add @mui/material @emotion/react @emotion/styled // 安装icon yarn add @mui/icons-material // 安装Mui的style模块(配置主题使用) yarn add '@mui/styles' 初始化项目模块 配置index.tsx入口文件

然后在index.tsx入口文件里面包裹react-redux提供的Provider引入store,store肯定会用到,然后包裹react-router-dom提供的BrowserRouter(有需要也可以用HashRouter替换,两种路由根据自己的项目需求进行选择)。

import ReactDOM from "react-dom"; import { BrowserRouter } from "react-router-dom"; import { Provider } from "react-redux"; import store from "./store/index"; import "./index.css"; import App from "./App"; ReactDOM.render( SET_WIDTH, SET_THEME } export default ActionType;

创建一个基础reducer

// @store/reducer/config.reducer.ts import { ConfigState, ReduxReducer } from "../../models/base.model"; import ActionType from "../action.type"; const initState: ConfigState = { width: 0 }; const reducer: ReduxReducer = (prevState = initState, { type, data }) => { switch (type) { case ActionType.SET_WIDTH: return { ...prevState, width: data }; default: return prevState; } }; export default reducer;

合并多个reducer并暴露

// @store/reducers/index.ts import { combineReducers } from "redux"; import ConfigReducer from "./config.reducer"; const reducers = combineReducers({ config: ConfigReducer }); export default reducers;

创建store

// @/store/index.ts import { createStore } from "redux"; import reducers from "./reducers"; export default createStore(reducers);

这样store就创建好了,然后在index.tsx中使用react-redux的Provider组件:

import ReactDOM from "react-dom"; import { BrowserRouter } from "react-router-dom"; import { Provider } from "react-redux"; import store from "./store/index"; import "./index.css"; import App from "./App"; ReactDOM.render( name: string; age: number; } // 组件的Props必须是满足接口IndexComponentProps的类型 const Index: FC = () => {...} // const Index = (props: IndexComponentProps) => {} // 这样就定义好了,l 使用Material 1.基本使用

基本使用很简单,参考官方文档就好。

例:

import { Button } from "@mui/material"; Contained Button 2.自定义主题

Mui提供主题默认变量,如果需要自定义主题就修改变量,然后传给Mui提供的ThemeProvider组件,如下:

// @app.tsx import { createTheme, ThemeProvider } from "@mui/material"; import "./App.less"; import Index from "./pages/Index"; function App() { const theme = createTheme({ palette: { mode: "light", primary: { main: "#0fa6a2", }, secondary: { main: "#8eb8e7" }, background: { paper: "", }, }, shape: { borderRadius: 4 }, }); return ( interface Theme { status: { danger: string; }; } // allow configuration using `createTheme` interface ThemeOptions { status?: { danger?: string; }; } }

利用上述内容编写第一个page demo: Index.tsx

// @pages/Index.tsx import { Button, Checkbox, FormControlLabel, FormGroup } from "@mui/material"; import { makeStyles } from "@mui/styles"; import { ThemeOptions } from "@mui/system"; import { Fragment } from "react"; import { useDispatch, useSelector } from "react-redux"; import { ConfigState, ReduxSelectorStateArg } from "../models/base.model"; import { setWidth } from "../store/actions/config.action"; console.log(makeStyles); const useStyles = makeStyles((theme: ThemeOptions) => { return { container: { background: theme?.palette?.secondary?.main, }, }; }); const Index = () => { const classes = useStyles(); const state: ConfigState = useSelector((state: ReduxSelectorStateArg) => state.config); const dispatch = useDispatch(); const setWidthState = () => { dispatch(setWidth(state.width + 1)); }; const disabled = state.width % 2 === 0; return ( state.width} } label="Label" /> } label="Disabled" /> ); }; export default Index;

注意:

ts如果想使用可选参数里面的属性,需要加?访问,不然TS编译器会报错:属性可能为定义引入makeStyles方法必须从"@mui/styles"引入,否则Mui会抛出错误(看了源码,生产环境应该不会抛错)之前使用react-redux提供的connect方法链接react-redux 和react-component,以获取store的状态state以及更改状态的方法dispatch,但是现在react-redux提供了useSelector和useDispatch这两个hook,更加方便操作store。引入createTheme方法也要注意引入位置,不能从"@mui/system"引入,要从"@mui/material"引入 Day 02 熟悉Mui color操作函数

"@mui/material/styles"库提供了alpha函数可以操作color的透明度

import { alpha } from "@mui/material/styles"; console.log(alpha("#375d81", 0.5))

查看alpha源码可以发现Mui不到提供了alpha,还提供了很多其他的颜色操作(类似Less)

export function hexToRgb(hex: string): string; // 十六进制的颜色转变为rgb格式的颜色 export function rgbToHex(color: string): string; // rgb颜色转变为十六进制 export function hslToRgb(color: string): string; // hsl转rgb export function decomposeColor(color: string): ColorObject; export function recomposeColor(color: ColorObject): string; export function getContrastRatio(foreground: string, background: string): number; export function getLuminance(color: string): number; export function emphasize(color: string, coefficient?: number): string; export function alpha(color: string, value: number): string; // 设置t export function darken(color: string, coefficient: number): string; // 暗化 export function lighten(color: string, coefficient: number): string; // 亮化 material-iconfont的使用 安装

按照material-icon官方介绍的使用方法(https://google.github.io/material-design-icons/#icon-font-for-the-web)

这里为了保证稳定性,我们就不去用谷歌提供的cdn了,利用他介绍的第二种方法在index.css里面加入如下代码:

@font-face { font-family: 'Material Icons'; font-style: normal; font-weight: 400; src: url(https://example.com/MaterialIcons-Regular.eot); /* For IE6-8 */ src: local('Material Icons'), local('MaterialIcons-Regular'), url(https://example.com/MaterialIcons-Regular.woff2) format('woff2'), url(https://example.com/MaterialIcons-Regular.woff) format('woff'), url(https://example.com/MaterialIcons-Regular.ttf) format('truetype'); } .material-icons { font-family: 'Material Icons'; font-weight: normal; font-style: normal; font-size: 24px; /* Preferred icon size */ display: inline-block; line-height: 1; text-transform: none; letter-spacing: normal; word-wrap: normal; white-space: nowrap; direction: ltr; /* Support for all WebKit browsers. */ -webkit-font-smoothing: antialiased; /* Support for Safari and Chrome. */ text-rendering: optimizeLegibility; /* Support for Firefox. */ -moz-osx-font-smoothing: grayscale; /* Support for IE. */ font-feature-settings: 'liga'; }

显然这个example.com是一个cdn链接示意,这里并不适合我们使用,于是我们直接访问谷歌提供的cdn链接:

访问链接https://fonts.googleapis.com/icon?family=Material+Icons得到css代码,直接复制粘贴到index.css文件中

/* fallback */ @font-face { font-family: 'Material Icons'; font-style: normal; font-weight: 400; src: url(https://fonts.gstatic.com/s/materialicons/v118/flUhRq6tzZclQEJ-Vdg-IuiaDsNc.woff2) format('woff2'); } .material-icons { font-family: 'Material Icons'; font-weight: normal; font-style: normal; font-size: 24px; line-height: 1; letter-spacing: normal; text-transform: none; display: inline-block; white-space: nowrap; word-wrap: normal; direction: ltr; -webkit-font-feature-settings: 'liga'; -webkit-font-smoothing: antialiased; }

这里还没完,这里可以看到字体资源是一条外部链接,同样的为了维持稳定我们可以直接访问这个链接下载改字体文件,然后存在本地工程资源目录,然后路径改为改字体文件的相对路径即可。

使用

第一种方法:

face

第二种方法:

import { Icon } from "@mui/material"; add_circle sx属性的使用

sx属性的值是一个对象,非常强大,支持原生的css属性以及Mui自己定义的一些属性以及简便写法等等,具体使用参考:https://mui.com/zh/system/basics/#when-to-use-it

React-router-dom练习与总结

总结:

可以摒弃之前react-router的注册方式,由于现在使用hooks风格的react函数式组件搭建项目就可以使用hooks风格的react-router相关api

注册路由:不用像之前一样组件化注册路由,而是使用路由表注册的方式:

// @routes/MainRoute.tsx import { RouteObject } from "react-router-dom"; import NotFound from "../components/common/NotFound"; import { Dashboard } from "../components/dashboard/Dashboard"; import MainLayout from "../components/layouts/Main"; const MainRoutes: RouteObject[] = [ { path: "/", element: , children: [ { path: "/test", element: , children: [ { path: "/test/:id", element: , }, ], }, ], }, { path: "*", element: , }, ]; export default MainRoutes; // 在MainRoute里面配置路由表,然后在Index里面生成路由组件(通过react-router-dom提供的hook api `useRoutes`)并暴露 // @routes/Index.tsx import { useRoutes } from "react-router-dom"; import MainRoutes from "./MainRoute"; const Routes = () => { return useRoutes(MainRoutes); }; export default Routes; // @App.tsx 然后在App组件里面渲染注册好的路由组建 **Outlet**的使用:Outlet类似于vue-router中的router-view以及angular路由中的router-outlet组件,使用方法不再赘述。

路由传参

在上面注册的路由表可以看出:在/test路径下注册了"/test/:id"子路由,带了id路由参数,那么在组件中可以通过useParams这个hook来获取

除了param,还可以通过searchParams传参,通过useSearchParams这个hook来获取参数值:

import { useParams, useSearchParams } from "react-router-dom"; export function Dashboard(props: any) { // 调用useParams可以直接返回params参数的值 let [searchParams] = useSearchParams(); // 这个searchParams的get方法传入需要获取的查询参数的键,返回对应的值 console.log(useParams(), searchParams.get("b")); return Dashboard; }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3